<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Lover-扫雷小游戏</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        a{
            list-style: none;
        }
        li {
            list-style: none;
        }

        html,body {
            height: 100%;
            width: 100%;
        }

        .dialog {
            display: flex;
            position: absolute;
            width: 100%;
            height: calc(100vh - 75px);
            top: 75px;
            background-color: rgba(107, 203, 241, 0.5);
            justify-content: center;
            align-items: center;
        }

        .dialog .info {
            width: 40%;
            height: 30%;
            background-color: pink;
            border-radius: 20px;
            box-shadow: 0 0 20px red;
            display: flex;
            flex-direction: column;
            justify-content: space-around;
            align-items: center;
        }

        .dialog .info span {
            font-size: 30px;
            color: white;
            text-shadow: 0 0 10px red;
        }

        .dialog .info span:first-child {
            justify-self: flex-start;
        }
        .dialog .info .choose {
            display: flex;
            flex-wrap: wrap;
            justify-content: space-evenly;
        }

        .dialog .info .choose .item {
            font-size: 15px;
            color: white;
            text-shadow: 0 0 10px black;
            border: none;
            border-radius: 10px;
            background-color: skyblue;
            width: 60px;
            height: 25px;
            margin: 5px 5px;
            box-shadow: 0 0 10px white;
            transition: 0.4s linear;
        }

        .dialog .info .choose .item:hover {
            cursor: pointer;
            box-shadow: 0 0 5px white inset;
        }

        .dialog .info .choose .item:active {
            box-shadow: 0 0 10px red;
        }


        .page-header {
            padding: 0 20px;
            height: 70px;
            background-color: rgba(255, 192, 203, 0.7);
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .page-header .title {
            cursor: pointer;
        }

        .page-header span {
            font-size: 20px;
            color: white;
            text-shadow: 0 0 5px red;
        }

        .content {
            height: calc(100vh - 70px);
            background-image: linear-gradient(#d9d9d9, pink, #d9d9d9);
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
        }

        .game-header {
            display: flex;
            justify-content: center;
        }

        .game-header div:nth-child(n) {
            font-size: 20px;
            color: white;
            margin: 10px 10px;
        }

        .game-space {
            background-color: #d9d9d9;
            border-radius: 20px;
            display: flex;
            flex-wrap: wrap;
            box-shadow: 0 0 20px white;
        }
        
        .mine {
            cursor: pointer;
            font-size: 15px;
            color: white;
            line-height: 30px;
            text-align: center;
            border-radius: 10px;
            width: 30px;
            height: 30px;
            background-color: rgb(253, 133, 233);
            margin: 5px;
            transition: 0.3s linear;
            background-repeat: no-repeat;
            background-position: center center;
        }

        .mine:hover {
            box-shadow: 0 0 10px black;
        }

        .mine:active {
            box-shadow: 0 0 5px #d9d9d9 inset;
        }
    </style>
</head>
<body>
    <div class="dialog">
        <div class="info">
            <span>Lover-Game</span>
            <span>难度选择</span>
            <div class="choose"></div>
        </div>
    </div>
    <header class="page-header">
        <span class="title">Lover-小游戏-扫雷</span>
    </header>
    <div class="content">
        <div class="game-header">
            <div class="level"></div>
            <div class="mine-count"></div>
            <div class="mines"></div>
            <div class="time"></div>
        </div>
        <div class="game-space">
        </div>
    </div>
</body>
<script>
    let gameRun = false
    const level = {
        '入门': [10, 10, 15],
        '新手': [10, 10, 25],
        '普通': [15, 15, 40], 
        '一般': [20, 20, 60], 
        '困难': [20, 20, 100], 
        '炼狱': [20, 20, 100]
    }
    const gameLevel = document.querySelector('.game-header .level')
    const gameMineCount = document.querySelector('.game-header .mine-count')
    const gameMines = document.querySelector('.game-header .mines')
    const gameTime = document.querySelector('.game-header .time')
    // 默认值
    let row = 10
    let col = 10
    let count = 10
    // 难度选择DOM元素
    const dialog = document.querySelector(".dialog")
    const choose = document.querySelector(".dialog .info .choose")
    // 添加难度选择
    for (let key in level){
        choose.innerHTML = choose.innerHTML + `<button class="item">${key}</button>`
    }
    // 获取所有选择
    const choose_lists = document.querySelectorAll(".dialog .info .choose .item")
    // 监听
    for (let i = 0; i < choose_lists.length; i++) {
        choose_lists[i].addEventListener('click', function(event){
            event.preventDefault()
            let num = level[choose_lists[i].innerHTML]
            row = num[0]
            col = num[1]
            count = num[2]
            gameLevel.innerHTML = '游戏难度:' + choose_lists[i].innerHTML
            gameMineCount.innerHTML = '地雷数:' + num[2]
            // 关闭对话框
            dialog.style = 'display: none;'
           initGame()
        })
    }

    

    // 生成随机坐标
    function generator(ans) {
        let r = Math.floor(Math.random() * row)
        let c = Math.floor(Math.random() * col)
        // 此处逻辑会造成重复问题！ TODO
        for (let i = 0; i < ans.length; i++) {
            if ( r === ans[i][0] && c === ans[i][1]){
                let ls = generator(ans)
                r = ls[0]
                c = ls[1]
                i = 0
            }
        }
        return [r, c]
    }

    // 制作随机坐标回调
    const generationMine = function() {
        const ans = []
        for (let i = 0; i < count; i++) {
            ans.push(generator(ans))
        }
        return ans
    }

    // 生成九宫格地雷数的回调
    const countMine = function(arr1, arr2) {
        for (let i = 0; i < arr2.length; i++) {
            let r = arr2[i][0]
            let c = arr2[i][1]
            for (let m = r - 1; m <= r + 1; m++) {
                for (let n = c - 1; n <= c + 1; n++) {
                    if (m >= 0 && n >= 0 && m < row && n < col) {
                        arr1[m][n] += 1
                    }
                }
            }
        }
        for (let i = 0; i < arr2.length; i++) {
            arr1[arr2[i][0]][arr2[i][1]] = -1
        }
    }

    // 递归翻开周围无雷的格子
    const uncoverHelper = function(r, c, visited, mines, mineCount) {
        if (r < 0 || r >= row || c < 0 || c >= col || visited[r][c][0] || mineCount[r][c] === -1) {
            return
        }
        visited[r][c][0] = true
        mines[r][c].innerHTML = mineCount[r][c] === 0 ? '' : mineCount[r][c]
        mines[r][c].style = 'background-color: #d9d9d9;'
        if (mineCount[r][c] === 0) {
            for (let m = r - 1; m <= r + 1; m++) {
                for (let n = c - 1; n <= c + 1; n++) {
                    uncoverHelper(m, n, visited, mines, mineCount)
                }
            }
        }
    }

    const clearScreen = function(mines, mineCount) {
        for (let i = 0; i < row; i++) {
            for (let j = 0; j < col; j++) {
                if (mineCount[i][j] === -1) {
                    mines[i][j].style = 'background-image: url(./img/地雷.png); background-repeat: no-repeat;background-color: transparent;'
                } else {
                    mines[i][j].innerHTML = mineCount[i][j] === 0 ? '' : mineCount[i][j]
                    mines[i][j].style = 'background-color: #d9d9d9;'
                }
            }
        }
    }


    

    // 初始化回调
    function initGame(){
        gameRun = true
        // 地雷容器DOM元素
        const mineContainer = document.querySelector('.game-space')
        // 制作地雷DOM元素
        for (let i = 0; i < row; i++) {
            mineContainer.innerHTML = mineContainer.innerHTML + `<div class="mine-row"></div>`
            const mineRow = document.querySelector(`.game-space .mine-row:nth-child(${i + 1})`)
            for (let j = 0; j < col; j++) {
                mineRow.innerHTML = mineRow.innerHTML + `<div class="mine"></div>`
            }
        }
        // 标记数组
        const flag = []
        // 初始化
        for (let i = 0; i < row; i++) {
            flag[i] = []
            for (let j = 0; j < col; j++) {
                 flag[i][j] = [false, false]
            }
        }
        // 生成地雷坐标
        const points = generationMine()
        // 九宫格内的地雷数
        const mineCount = []
        for (let i = 0; i < row; i++) {
            mineCount[i] = []
            for (let j = 0; j < col; j++) {
                mineCount[i][j] = 0
            }
        }
        // 计算坐标
        countMine(mineCount, points)
        // 地雷DOM元素数组
        const mines = []
        // 事件监听
        for (let i = 0; i < row; i++) {
            mines[i] = []
            for (let j = 0; j < col; j++) {
                const m = document.querySelector(`.mine-row:nth-child(${i + 1}) .mine:nth-child(${j + 1})`)
                mines[i][j] = m
                // 事件监听-标记
                m.addEventListener('contextmenu', function(event) {
                    event.preventDefault()
                    if (!flag[i][j][0]) {
                        m.style = `background-image: ${flag[i][j][1] ? "none" : "url(./img/标记.png)" };`
                        flag[i][j][1] = !flag[i][j][1]
                    }
                })
                
                // 事件监听-打开
                m.addEventListener('click', function(event) {
                    if (!flag[i][j][1]) {
                        if (mineCount[i][j] === -1) {
                            m.style = 'background-image: url(./img/地雷.png); background-repeat: no-repeat;background-color: transparent;'
                            gameRun = false
                            // 将所有地雷全部拆开
                            clearScreen(mines, mineCount)
                            confirm("游戏失败！")
                        } else {
                            // 非地雷事件
                            uncoverHelper(i, j, flag, mines, mineCount)
                        }
                        
                    }
                })
            }
        }
        
        // 游戏开始后的监听异步线程
        // 判断是否胜利回调
        let isSuccess = setInterval(function () {
            let all = 0
            let label = 0
            for (let i = 0; i < flag.length; i++) {
                for (let j = 0; j < flag[i].length; j++) {
                    all += flag[i][j][0] ? 1 : 0
                    label += flag[i][j][1]
                }
            }
            gameMines.innerHTML = '剩余地雷数:' + (count - label)
            !gameRun ? clearInterval(isSuccess) : null
            if (all === row * col - count ){
                confirm('胜利!!!')
                gameRun = false
                clearInterval(isSuccess)
            }
        }, 300)
        let startInstance = Date.now()
        // 使用时间
        let useTime = setInterval(function(){
            gameTime.innerHTML = '使用时间：' + ((Date.now() - startInstance) / 1000) + 's'
            !gameRun ? clearInterval(useTime) : null
        }, 100)
    
    }
    
    
</script>
</html>